package edu.lingnan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import edu.lingnan.dto.result.StudentBookingInfo;
import edu.lingnan.entity.Booking;
import edu.lingnan.entity.ClassRoom;
import edu.lingnan.entity.Seat;
import edu.lingnan.entity.Student;
import edu.lingnan.mapper.BookingMapper;
import edu.lingnan.mapper.ClassRoomMapper;
import edu.lingnan.mapper.SeatMapper;
import edu.lingnan.mapper.StudentMapper;
import edu.lingnan.service.ClassRoomService;
import edu.lingnan.service.StudentService;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Service
@Transactional
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private BookingMapper bookingMapper;
    @Resource
    private SeatMapper seatMapper;
    @Resource
    private ClassRoomMapper classRoomMapper;

    @Resource
    private ThreadPoolExecutor executor;

    @Override
    public Student checkLogin(Map<String, Object> map) {
        List<Student> students = studentMapper.selectByMap(map);
        if (CollectionUtils.isEmpty(students)) {
            return null;
        } else {
            return students.get(0);
        }
    }

    @Override
    public List<Student> findAllStudentRegisterInfo(String college) {
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        if (!ObjectUtils.isEmpty(college)){
            wrapper.eq(Student::getSCollege, college);
        }
        // wrapper.select("s_id","s_name").eq("s_status","2");
        wrapper.eq(Student::getSStatus, "2");
        List<Student> students = studentMapper.selectList(wrapper);
        if (students == null){
            return Collections.EMPTY_LIST;
        }
        return students;
    }

    @Override
    public int updateOrDeleteStudentStatus(Student student) {
        int i = -1;
        if ("1".equals(student.getSStatus())) {
            UpdateWrapper<Student> wrapper = new UpdateWrapper<>();
            wrapper.eq("s_id", student.getSId());
            Student student2 = new Student();
            student2.setSStatus("1");
            i = studentMapper.update(student2, wrapper);
        }
        if ("0".equals(student.getSStatus())) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("s_id", student.getSId());
            i = studentMapper.deleteByMap(map);
        }
        return i;
    }

    //    判断该学生是否已经注册成功并通过审核
    //返回值 1代表成功，2代表用户名不存在，3代表密码错误，4代表未通过审核
    @Override
    public int checkStudent(Student student) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("s_id", student.getSId());
        List<Student> students = studentMapper.selectByMap(map);
        Student student1 = null;
        if (students.size() > 0) {
            student1 = students.get(0);
            if (student1.getSPassword().equals(student.getSPassword()) && student1.getSStatus().equals("1")) {
                return 1;
            } else if (student1.getSPassword().equals(student.getSPassword()) && student1.getSStatus().equals("2")) {
                return 4;
            } else if (!student1.getSPassword().equals(student.getSPassword())) {
                return 3;
            }
        }


        return 2;
    }

    //    查询学生有效预约记录的相关信息，前提条件，该学生已经预约到座位并且该座位正在生效
    @Override
    public StudentBookingInfo queryUseFulStudentBookingInfo(String sId) {
        List<StudentBookingInfo> infoList = bookingMapper.selectJoinList(StudentBookingInfo.class,
                new MPJLambdaWrapper<>()
                        .selectAs(Student::getSId, StudentBookingInfo::getSId)
                        .selectAs(Student::getSPhone, StudentBookingInfo::getSPhone)
                        .selectAs(Student::getSName, StudentBookingInfo::getSName)
                        .selectAs(Student::getSPassword, StudentBookingInfo::getSPassWord)
                        .selectAs(Student::getSClass, StudentBookingInfo::getSClass)
                        .selectAs(Student::getSCollege, StudentBookingInfo::getSCollege)
                        .selectAs(Student::getSGrade, StudentBookingInfo::getSGrade)
                        .selectAs(Seat::getSeatNum, StudentBookingInfo::getSeatNum)
                        .selectAs(ClassRoom::getRBuilding, StudentBookingInfo::getRBuilding)
                        .selectAs(ClassRoom::getRRoom, StudentBookingInfo::getRRoom)
                        .selectAs(Booking::getBId, StudentBookingInfo::getBId)
                        .selectAs(Booking::getBStartTime, StudentBookingInfo::getBStartTime)
                        .selectAs(Booking::getBEndTime, StudentBookingInfo::getBEndTime)
                        .innerJoin(Student.class, Student::getSId, Booking::getSId)
                        .innerJoin(Seat.class, Seat::getSeatId, Booking::getSeatId)
                        .innerJoin(ClassRoom.class, ClassRoom::getRId, Seat::getRId)
                        .eq(Booking::getBUseful, 1)
                        .eq(Student::getSId,sId));


        StudentBookingInfo studentBookingInfo = null;
        if(infoList.size() > 0){
           studentBookingInfo = infoList.get(0);
        }
        return studentBookingInfo;

        //StudentBookingInfo studentBookingInfo = new StudentBookingInfo();
        ////获取学生信息
        //CompletableFuture<Student> studentCompletableFuture = CompletableFuture.supplyAsync(() -> {
        //    Student student = this.baseMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getSId, sId));
        //    return student;
        //}, executor);
        ////获取该学生的预约信息
        //CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
        //    Booking booking = bookingMapper.selectOne(new LambdaQueryWrapper<Booking>()
        //            .eq(Booking::getSId, sId)
        //            .eq(Booking::getBUseful, 1));
        //    studentBookingInfo.setBId(booking.getBId())
        //            .setBStartTime(booking.getBStartTime())
        //            .setBEndTime(booking.getBEndTime());
        //    return booking;
        //}, executor).thenApply((booking) -> {
        //    //获取座位信息
        //    Seat seat = seatMapper.selectById(booking.getSeatId());
        //    studentBookingInfo.setSeatNum(Integer.valueOf(seat.getSeatNum()));
        //    return seat;
        //}).thenAccept((seat) -> {
        //    //获取教室信息
        //    ClassRoom classRoom = classRoomMapper.selectById(seat.getRId());
        //    studentBookingInfo
        //            .setRBuilding(classRoom.getRBuilding())
        //            .setRRoom(classRoom.getRRoom());
        //});
        //
        //
        //Student student = studentCompletableFuture.join();
        //studentBookingInfo
        //        .setSCollege(student.getSCollege())
        //        .setSGrade(student.getSGrade())
        //        .setSPhone(student.getSPhone())
        //        .setSClass(student.getSClass())
        //        .setSId(student.getSId())
        //        .setSName(student.getSName())
        //        .setSPassWord(student.getSPassword());
        //CompletableFuture.allOf(completableFuture);
        //return studentBookingInfo;
    }

    @Override
    public boolean updateStudentInfo(Student student) {
        UpdateWrapper<Student> wrapper = new UpdateWrapper<>();
        wrapper.eq("s_id", student.getSId());
        if (student.getSPassword() != null && student.getSPassword() != "") {
            wrapper.set("s_passWord", student.getSPassword());
        }
        if (student.getSClass() != null && student.getSClass() != "") {
            wrapper.set("s_class", student.getSClass());
        }
        if (student.getSCollege() != null && student.getSCollege() != "") {
            wrapper.set("s_college", student.getSCollege());
        }
        if (student.getSGrade() != null && student.getSGrade() != "") {
            wrapper.set("s_grade", student.getSGrade());
        }
        if (student.getSName() != null && student.getSName() != "") {
            wrapper.set("s_name", student.getSName());
        }
        boolean update = this.update(wrapper);
        if (update) {
            return true;
        }
        return false;
    }
}
